package cn.sinjet.model.dynamicfont;

import java.io.InputStream;

import com.mgroup.wazehelper.R;

import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
import cn.sinjet.carassist.SinjetApplication;
import cn.sinjet.communication.bluetooth.BluetoothModel;
import cn.sinjet.model.mcuupgrade.MCUUpgradeCommonFunction;

public class DynamicFontModel {
	private static DynamicFontModel dynamicFontModel = null;
	private byte[] fontData = null;
	Context context;
	public synchronized static DynamicFontModel getInstance() {
		if (dynamicFontModel == null) {
			dynamicFontModel = new DynamicFontModel();
		}
		return dynamicFontModel;
	}
	
	public DynamicFontModel(){
		context = SinjetApplication.getInstance().getApplicationContext();
	}
	
	private void getFontData() {
		if (fontData != null) {
			return;
		}
		
		try {
			Resources res = context.getResources();
//			File file = new File(this.getClass().getResource("dzks1516.hz").toURI());
//			FileInputStream fin = new FileInputStream(file);
			InputStream ins = res.openRawResource(R.raw.dzks1516);
			int length = ins.available();
			fontData = new byte[length];
			ins.read(fontData);
			ins.close();
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	
	private int getGBFontDataOffset(byte[] gbkByte)
	{
		return ((MCUUpgradeCommonFunction.getUnsignedByte(gbkByte[0])-0xB0)*94+(MCUUpgradeCommonFunction.getUnsignedByte(gbkByte[1])-0xA1))*32;
	}
	private void packAndMsg(byte[] message,int len) {    
	    byte[] szMsg = new byte[len + 5];
		szMsg[0] = (byte) 0xFF;
		szMsg[1] = (byte) 0x55;
		szMsg[2] = (byte) (len + 1);
		szMsg[3] = (byte) 0x36;
		System.arraycopy(message, 0, szMsg, 4, len);
		
		byte sum = 0;
		int s = 0;
		int i = 0;
		for (i = 2; i < len + 4; i++) {
			s += (szMsg[i] & 0xFF);
		}
		sum = (byte) (s & 0xFF);
		szMsg[len + 4] = sum;
		BluetoothModel.getInstance().sendMessage(szMsg);
		
		final StringBuilder stringBuilder = new StringBuilder(message.length);
		for (byte byteChar : message)
			stringBuilder.append(String.format("%02X ", byteChar));
		Log.i("dynamic_font","onSend: "+ stringBuilder.toString());
	}

	private void sendFontData(byte[] utf8Byte,int offset,int seg)
	{
	    if (fontData.length < offset+(seg+1)*8)
	    {
	        return;
	    }
	    
	    byte[] buf = new byte[1+3+1+8];
		buf[0] = 0x10;
		System.arraycopy(utf8Byte, 0, buf, 1, 3);
		buf[4] = (byte) seg;
		System.arraycopy(fontData, offset+seg*8, buf, 5, 8);
		
		packAndMsg(buf,buf.length);
	}
	
	private void sendFontDataLongFrame(byte index,int offset)
	{
		if (fontData.length < offset + 32)
		{
			return;
		}
		
		byte[] buf = new byte[1+1+32];
		buf[0] = 0x11;
		buf[1] = index;
		System.arraycopy(fontData, offset, buf, 2, 32);
		
		packAndMsg(buf,buf.length);
	}
	
	public int onRecvDynamicFontMsg(byte[] message) {
		getFontData();
		
		if (0x36 == message[0])
		{
			switch (message[1])
			{
			case 0x11:
				try {
					int offset = 2;
					int length = message.length;
					boolean haveStorageIndex;
					byte storageIndex = 0;
					
					byte fontHaveMask;
					byte utf8Byte[] = new byte[4];
					utf8Byte[3] = 0;
					
					while (offset + 4 <= length)
					{
						System.arraycopy(message, offset, utf8Byte, 0, 3);
						offset += 3;
						fontHaveMask = message[offset];
						offset += 1;
						
						if (offset < length)
						{
							haveStorageIndex = true;
							storageIndex = message[offset];
							offset += 1; 
						}
						else
						{
							haveStorageIndex = false;
						}
						
						byte gbkByte[] = new String(utf8Byte,"utf-8").getBytes("gbk");
						int GBOffset = getGBFontDataOffset(gbkByte);
						
						if (haveStorageIndex)
						{
							sendFontDataLongFrame(storageIndex,GBOffset);
						}
						else
						{
							for (int i = 0;i < 4;i++)
							{
			                    if (((1<<i) & fontHaveMask) == 0)
			                    {
			                    	sendFontData(utf8Byte,GBOffset,i);
			                    }
							}
						}
					}

				}
				catch (Exception ex) {
					ex.printStackTrace();
				}
				break;
			default:
				break;
			}
		}
		
		return 0;
	}
}